package com.crm.util;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang3.time.DateUtils;

public class BeanUtil {
	private static String simpleDataTypePrefix = "java.lang.";
	private static Map<String, String> SimpleDataTypeMap = new HashMap<>();
	static {
		loadDataType();
	}
	

	// Bean --> Map
	public static Map<String, Object> transBean2Map(Object obj) {
		if (obj == null) {
			return null;
		}
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
			PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
			for (PropertyDescriptor property : propertyDescriptors) {
				String key = property.getName();
				// 过滤class属性
				if (!key.equals("class")) {
					// 得到property对应的getter方法
					Method getter = property.getReadMethod();
					Object value = getter.invoke(obj);
					map.put(key, value);
				}

			}
		} catch (Exception e) {
			System.out.println("transBean2Map Error " + e);
		}
		return map;

	}

	// Map --> Bean
	public static Object transMap2Bean(Map<String, Object> map, Class<?> T)
			throws Exception {
		Object obj = T.newInstance();
		try {
			BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
			PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
			for (PropertyDescriptor property : propertyDescriptors) {
				String key = property.getName();
				if (map.containsKey(key)) {
					Object value = map.get(key);
					if (value instanceof String && value != null) {
						String simpleName = property.getPropertyType().getSimpleName();
						if (SimpleDataTypeMap.containsKey(simpleName) || SimpleDataTypeMap.containsValue(simpleName)) {
							String fullTypeName = getFullTypeName(simpleName);
							value = "String".equals(simpleName) ? value
									: Class.forName(fullTypeName).getMethod("valueOf", String.class).invoke("valueOf",
											value);
						} else if ("Date".equals(simpleName)) {
							value = parDate((String) value);
						} else {
							throw new Exception("类型找不到:" + property.getPropertyType().getName());
						}

					}
					// 得到property对应的setter方法
					Method setter = property.getWriteMethod();
					setter.setAccessible(true);
					setter.invoke(obj, value);
				}

			}

		} catch (Exception e) {
			System.out.println("transMap2Bean Error " + e);
			throw new Exception("转换异常");
		}

		return obj;

	}
	/**
	 * 返回基本数据类型全称
	 * @param Name
	 * @return
	 */
	private static String getFullTypeName(String Name) {
		Name = simpleDataTypePrefix + Name.substring(0, 1).toUpperCase() + Name.substring(1);
		return Name;
	}
	/**
	 * 转换日期
	 * @param value
	 * @return
	 * @throws ParseException
	 */
	private static Date parDate(String value) throws ParseException{
		Date date = null;
		try {
			date =DateUtils.parseDate(value, "yyyy-MM-dd HH:mm:ss");
		} catch (ParseException e) {
			date = DateUtils.parseDate(value, "yyyy-MM-dd");
		}
		return date;
	}
	/**
	 * 填充数据类型
	 */
	private static void loadDataType(){
		SimpleDataTypeMap.put("byte", "Byte");
		SimpleDataTypeMap.put("short", "Short");
		SimpleDataTypeMap.put("int", "Integer");
		SimpleDataTypeMap.put("long", "Long");
		SimpleDataTypeMap.put("float", "Float");
		SimpleDataTypeMap.put("double", "Double");
		SimpleDataTypeMap.put("boolean", "Boolean");
		SimpleDataTypeMap.put("char", "Char");
		SimpleDataTypeMap.put("String", "String");
	}

	public static void main(String[] args) throws Exception, IllegalAccessException {
		/*Map<String, Object> map = new HashMap<>();
		map.put("payDate", "2016-07-09 23:59:59");
		map.put("projectName", "9");
		Object obj = transMap2Bean(map, FinanceSchoolIncome.class);
		FinanceSchoolIncome consult = (FinanceSchoolIncome) obj;
		System.out.println(DateUtils.parseDate("2016-07-09", "yyyy-MM-dd HH:mm:ss") + "," + consult.getPayDate() + "," + consult.getMoney() + ","
				+ consult.getProjectName());*/

	}

}
